package fun.yyds.utils;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

@Component
public class LogUtil {

    @Value("${log.file.path:./logs}")
    private String logBasePath;

    @Value("${log.max.rows:1000}")
    private int maxLogRows;

    private static String staticLogBasePath;
    private static int staticMaxLogRows;
    private static final ReentrantLock lock = new ReentrantLock();
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private static String type = "系统日志";
    private static String info = "info";
    private static String error = "error";
    private static String warn = "warn";
    private static String SYS = "XTYW";
    private static String module = "公共模块";
    private static String ip = "127.0.0.1";
    private static String opOK = "成功";
    private static String opFiled = "失败";

    @PostConstruct
    public void init() {
        staticLogBasePath = logBasePath;
        staticMaxLogRows = maxLogRows;
        ip = IpUtils.getLocalIp();
    }

    /**
     * 写入日志到xtyw.log文件，并确保不超过最大行数限制
     *
     * @param logJson 完整的JSON日志字符串
     */
    public static void writeLog(String logJson) {
        lock.lock();
        try {
            // 构建完整文件路径
            Path logDir = Paths.get(staticLogBasePath);
            Path logFile = logDir.resolve("xtyw.log");

            // 确保目录存在
            if (!Files.exists(logDir)) {
                Files.createDirectories(logDir);
            }

            // 确保文件存在
            if (!Files.exists(logFile)) {
                Files.createFile(logFile);
            }

            // 读取现有日志内容
            List<String> lines = new ArrayList<>();
            if (Files.size(logFile) > 0) {
                try (BufferedReader reader = Files.newBufferedReader(logFile, StandardCharsets.UTF_8)) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        lines.add(line);
                    }
                }
            }

            // 添加新日志
            lines.add(logJson);

            // 如果超过最大行数，删除最老的行
            while (lines.size() > staticMaxLogRows) {
                lines.remove(0);
            }

            // 重新写入文件
            try (BufferedWriter writer = Files.newBufferedWriter(logFile, StandardCharsets.UTF_8)) {
                for (String line : lines) {
                    writer.write(line);
                    writer.newLine();
                }
            }
        } catch (IOException e) {
            System.err.println("写入日志失败: " + e.getMessage());
        } finally {
            lock.unlock();
        }
    }

    /**
     * 创建标准格式的日志JSON字符串
     */
    public static void jsonLog(String logSource, String type, String level,
                               String module, String content, String operaResult,
                               String ip, String userAccount) {
        String format = String.format("{\"logSource\":\"%s\",\"type\":\"%s\",\"level\":\"%s\"," +
                        "\"module\":\"%s\",\"content\":\"%s\",\"operaResult\":\"%s\"," +
                        "\"operaTime\":\"%s\",\"ip\":\"%s\",\"userAccount\":\"%s\"}",
                logSource, type, level, module, content, operaResult,
                LocalDateTime.now().format(TIME_FORMATTER), ip, userAccount);
        writeLog(format);
    }

    public static void infoLog(String content) {
        jsonLog(SYS, type, info, module, content, opOK, ip, "sys");
    }

    public static void errorLog(String content) {
        jsonLog(SYS, type, error, module, content, opFiled, ip, "sys");
    }

    public static void warnLog(String content) {
        jsonLog(SYS, type, warn, module, content, opFiled, ip, "sys");
    }

}